package com.imooc.business.util.report;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.DateFormat;
import java.text.DateFormatSymbols;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.*;

/**
 * @Author Tim
 * @Description:
 * @Version 1.0
 */
public class DateUtil {
    private static final Logger log = LoggerFactory.getLogger(DateUtil.class);
    public static final String YYYY_MM_DD_HHMMSS_SSS = "yyyy-MM-dd HH:mm:ss.SSS";
    public static final String YYYY_MM_DD_HHMMSS = "yyyy-MM-dd HH:mm:ss";
    public static final String YYYY_MM_DD_HHMM = "yyyy-MM-dd HH:mm";
    public static final String YYYY_MM_DD_HH = "yyyy-MM-dd HH";
    public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
    public static final String YYYYMMDDHHMMSS_SSS = "yyyyMMddHHmmssSSS";
    public static final String YYYY_MM_DD = "yyyy-MM-dd";
    public static final String YYYYMMDD_DOT = "yyyy.MM.dd";
    public static final String YYYY_MM_DD_S = "yyyy/MM/dd";
    public static final String YYYY_W = "yyyy-w";
    public static final String YYYY_MM = "yyyy-MM";
    public static final String YYYY = "yyyy";
    public static final String MMM = "MM月";
    public static final String MM = "MM";
    public static final String DD = "dd";
    public static final String MM_DD = "MM-dd";
    public static final String MM_SS = "mm:ss";
    public static final String YY_MM = "yy-MM";
    public static final String YYYY_MM_ZH_CN = "yyyy年MM月";
    public static final String YYYY_MM_ZH_CN1 = "yyyy年M月";
    public static final String YYYY_MM_DD_HHMMSS_ZH_CN = "yyyy年MM月dd日  HH:mm:ss";
    public static final String YYYY_MM_DD_HHMM_ZH_CN = "yyyy年MM月dd日  HH:mm";
    public static final String YYYYMMDD = "yyyyMMdd";
    public static final String YYYYMM = "yyyyMM";
    public static final String YYYY_MM_DD_ZH_CN = "yyyy年MM月dd日";
    public static final String MM_DD_ZH_CN = "MM月dd日";
    public static final String MM_DOT_DD = "MM.dd";
    public static final String MM_DD_HHMM = "MM-dd HH:mm";
    public static final String MM_DD_HHMM_ZH_CN = "MM月dd日 HH:mm";
    public static final String MM_DD_HHMMSS_ZH_CN = "MM月dd日 HH:mm:ss";
    public static final String HHMM = "HH:mm";
    public static final String MMdd = "MM/dd";
    public static final String Md = "M/d";
    public static final String M = "M月";
    public static final String Y = "yyyy年";
    public static final String[] DAY_NAMES = new String[]{"周日", "周一", "周二", "周三", "周四", "周五", "周六"};
    public static final String LOOK_TIME_VALUE = "%s'";
    public static final String LOOK_TIME_VALUE_MILL = "%s''";
    public static final String FIRST_SEMESTER_START_DAY = "02-01";
    public static final String FIRST_SEMESTER_END_DAY = "08-31";
    public static final String SECOND_SEMESTER_START_DAY = "09-01";
    public static final String SECOND_SEMESTER_END_DAY = "01-31";
    public static final String YEAR_START = "-09-01";
    public static final String YEAR_END = "-08-31";
    private static Map<String, String> typeMap = new HashMap();

    private DateUtil() {
    }

    public static Calendar convertToCalendar(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar;
    }

    public static Calendar convertToCalendar(long timeInMillis) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(timeInMillis);
        return calendar;
    }

    public static long getMillis(Date date) {
        return convertToCalendar(date).getTimeInMillis();
    }

    public static int getSecond(Date date) {
        return convertToCalendar(date).get(13);
    }

    public static int getMinute(Date date) {
        return convertToCalendar(date).get(12);
    }

    public static int getHour(Date date) {
        return convertToCalendar(date).get(11);
    }

    public static int getDay(Date date) {
        return convertToCalendar(date).get(5);
    }

    public static int getWeekDay(Date date) {
        return convertToCalendar(date).get(7);
    }

    public static int getMonth(Date date) {
        return convertToCalendar(date).get(2) + 1;
    }

    public static int getYear(Date date) {
        return convertToCalendar(date).get(1);
    }

    public static Date addDate(Date date, long day) {
        return convertToCalendar(getMillis(date) + day * 24L * 3600L * 1000L).getTime();
    }

    public static int diffDate(Date endDate, Date startDate) {
        return (int)((getMillis(endDate) - getMillis(startDate)) / 86400000L);
    }

    public static Date getYesterday() {
        Calendar c = convertToCalendar(new Date());
        c.add(5, -1);
        return c.getTime();
    }

    public static Date getOffsetTimeBySecond(Date date, int seconds) {
        Calendar c = convertToCalendar(date);
        c.add(13, seconds);
        return c.getTime();
    }

    public static Date getOffsetTimeByMinute(Date date, int minutes) {
        Calendar c = convertToCalendar(date);
        c.add(12, minutes);
        return c.getTime();
    }

    public static Date getOffsetTimeByHour(Date date, int hours) {
        Calendar c = convertToCalendar(date);
        c.add(10, hours);
        return c.getTime();
    }

    public static Date getNow() {
        return new Date();
    }

    public static String getNowString(String pattern) {
        return format(new Date(), pattern);
    }

    public static String getNowString() {
        return format(new Date(), "yyyyMMddHHmmss");
    }

    public static String format(Date date, String pattern) {
        if (date != null) {
            SimpleDateFormat sdf = new SimpleDateFormat(pattern, Locale.CHINA);
            return sdf.format(date);
        } else {
            return null;
        }
    }

    public static String formatMillDateTime(Date date) {
        return format(date, "yyyy-MM-dd HH:mm:ss.SSS");
    }

    public static Date formatMillTimeDate(String time) {
        try {
            return (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).parse(time);
        } catch (Exception var2) {
            return null;
        }
    }

    public static String formatDateTime(Date date) {
        return format(date, "yyyy-MM-dd HH:mm:ss");
    }

    public static String formatDateYYYYMMDD(Date date) {
        return format(date, "yyyy-MM-dd");
    }

    public static String formatDate(Date date) {
        return format(date, "yyyyMMdd");
    }

    public static String formatTime(Date date) {
        return format(date, "yyyyMMddHHmmss");
    }

    public static String formatNowTime() {
        return formatNowTime("yyyyMMddHHmmss");
    }

    public static String formatNowTime(String pattern) {
        return format(getNow(), pattern);
    }

    public static Date parseDate(String date) {
        if (StringUtils.isBlank(date)) {
            return null;
        } else {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
                return sdf.parse(date);
            } catch (Exception var2) {
                log.error("", var2);
                return null;
            }
        }
    }

    public static Date parseDate(Integer date) {
        return Objects.isNull(date) ? null : parseDate(date.toString());
    }

    public static Date parseTime(String date) {
        if (StringUtils.isBlank(date)) {
            return null;
        } else {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                return sdf.parse(date);
            } catch (Exception var2) {
                log.error("", var2);
                return null;
            }
        }
    }

    public static Date parseDate(String date, String pattern) {
        if (StringUtils.isBlank(date)) {
            return null;
        } else {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat(pattern);
                return sdf.parse(date);
            } catch (Exception var3) {
                log.error("", var3);
                return null;
            }
        }
    }

    public static Date parse(String date, String pattern) {
        if (StringUtils.isBlank(date)) {
            return null;
        } else {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat(pattern);
                return sdf.parse(date);
            } catch (Exception var3) {
                log.error("", var3);
                return null;
            }
        }
    }

    public static int compareGapInSeconds(Date one, Date two) {
        return two.compareTo(one);
    }

    public static Date getAfterDate(Date date, int afterDays) {
        long time = date.getTime();
        long ibeforeDays = (long)afterDays * 1000L * 60L * 60L * 24L;
        return new Date(time + ibeforeDays);
    }

    public static Date getBeforeMin(Date date, int min) {
        long time = date.getTime();
        long duration = (long)min * 1000L * 60L;
        return new Date(time - duration);
    }

    public static Date getBeforeHour(Date date, int hour) {
        long time = date.getTime();
        long duration = (long)hour * 1000L * 60L * 60L;
        return new Date(time - duration);
    }

    public static Date getBeforeDate(Date date, int beforeDays) {
        long time = date.getTime();
        long ibeforeDays = (long)beforeDays * 1000L * 60L * 60L * 24L;
        return new Date(time - ibeforeDays);
    }

    public static Date getBeforeWeek(Date date, int beforeWeeks) {
        return getBeforeDate(date, beforeWeeks * 7);
    }

    public static Date getBeforeMonth(Date date, int beforeMonth) {
        int month = date.getMonth();
        int year = date.getYear();
        int m = month - beforeMonth;
        if (m > 0) {
            date.setMonth(m);
        } else {
            while(true) {
                if (m >= 0) {
                    date.setYear(year);
                    date.setMonth(m);
                    break;
                }

                --year;
                m += 12;
            }
        }

        return date;
    }

    public static Date getBeforeYear(Date date, int beforeYear) {
        Calendar canlendar = Calendar.getInstance();
        canlendar.setTime(date);
        canlendar.add(1, -beforeYear);
        return canlendar.getTime();
    }

    public static Date getBackMonth(Date date) {
        Calendar canlendar = Calendar.getInstance();
        canlendar.setTime(date);
        canlendar.add(2, -1);
        return canlendar.getTime();
    }

    public static Date getAfterMonth(Date date) {
        Calendar canlendar = Calendar.getInstance();
        canlendar.setTime(date);
        canlendar.add(2, 1);
        return canlendar.getTime();
    }

    public static Date getAfterMonth(Date date, int afterMonth) {
        Calendar canlendar = Calendar.getInstance();
        canlendar.setTime(date);
        canlendar.add(2, afterMonth);
        return canlendar.getTime();
    }

    public static Date getBackMonthBeginDay(Date date) {
        Calendar canlendar = Calendar.getInstance();
        canlendar.setTime(date);
        canlendar.add(2, -1);
        canlendar.set(5, 1);
        canlendar.set(11, 0);
        canlendar.set(12, 0);
        canlendar.set(13, 0);
        return canlendar.getTime();
    }

    public static Date getBackMonthEndDay(Date date) {
        Calendar canlendar = Calendar.getInstance();
        canlendar.setTime(date);
        canlendar.add(2, -1);
        canlendar.set(5, canlendar.getActualMaximum(5));
        canlendar.set(11, 23);
        canlendar.set(12, 59);
        canlendar.set(13, 59);
        canlendar.set(14, 999);
        return canlendar.getTime();
    }

    public static Date getBackDate(Date date) {
        Calendar canlendar = Calendar.getInstance();
        canlendar.setTime(date);
        canlendar.add(5, -1);
        return canlendar.getTime();
    }

    public static Date getDay(Date date, int day) {
        Calendar canlendar = Calendar.getInstance();
        canlendar.setTime(date);
        canlendar.add(5, day);
        return canlendar.getTime();
    }

    public static int getWeekOfYear(Date date) {
        Calendar c = new GregorianCalendar();
        c.setFirstDayOfWeek(2);
        c.setTime(date);
        return c.get(3);
    }

    public static int diffDay(Date t1, Date t2) {
        if (t1 != null && t2 != null) {
            long l = t1.getTime() - t2.getTime();
            if (l > 0L) {
                long hour = l / 3600000L;
                if (hour > 24L) {
                    return hour % 24L == 0L ? (int)(hour / 24L) : (int)(hour / 24L + 1L);
                } else {
                    return 1;
                }
            } else {
                return 0;
            }
        } else {
            return 0;
        }
    }

    public static final String toGMT(Date date) {
        Locale aLocale = Locale.US;
        DateFormat fmt = new SimpleDateFormat("EEE,d MMM yyyy hh:mm:ss z", new DateFormatSymbols(aLocale));
        fmt.setTimeZone(TimeZone.getTimeZone("GMT"));
        return fmt.format(date);
    }

    public static Calendar getFirstDayOfWeek() {
        Calendar monday = Calendar.getInstance();
        return getADayOfWeek(monday, 2);
    }

    public static Date getFirstDayOfWeek(Date day) {
        Calendar monday = Calendar.getInstance();
        monday.setTime(day);
        return getADayOfWeek(monday, 2).getTime();
    }

    public static Calendar getFirstDayOfWeek(Calendar day) {
        Calendar monday = (Calendar)day.clone();
        return getADayOfWeek(monday, 2);
    }

    public static Calendar getLastDayOfWeek() {
        Calendar sunday = Calendar.getInstance();
        return getADayOfWeek(sunday, 1);
    }

    public static Date getLastDayOfWeek(Date day) {
        Calendar c = Calendar.getInstance();
        c.setTime(day);
        return getADayOfWeek(c, 1).getTime();
    }

    public static Calendar getLastDayOfWeek(Calendar day) {
        Calendar sunday = (Calendar)day.clone();
        return getADayOfWeek(sunday, 1);
    }

    private static Calendar getADayOfWeek(Calendar day, int dayOfWeek) {
        int week = day.get(7);
        if (week == dayOfWeek) {
            return day;
        } else {
            int diffDay = dayOfWeek - week;
            if (week == 1) {
                diffDay -= 7;
            } else if (dayOfWeek == 1) {
                diffDay += 7;
            }

            day.add(5, diffDay);
            return day;
        }
    }

    public static String getStringTime(Long ts) {
        if (ts != null && ts > 0L) {
            Date date = new Date(ts);
            return format(date, "yyyy-MM-dd HH:mm:ss.SSS");
        } else {
            return null;
        }
    }

    public static Date getDateTime(Long ts) {
        return ts != null && ts > 0L ? new Date(ts) : null;
    }

    public static Date getMonthBeginDay(Date date) {
        if (date == null) {
            return null;
        } else {
            Calendar c = Calendar.getInstance();
            c.setTime(date);
            c.set(5, 1);
            c.set(11, 0);
            c.set(12, 0);
            c.set(13, 0);
            c.set(14, 0);
            return c.getTime();
        }
    }

    public static Date getMonthEndDay(Date date) {
        if (date == null) {
            return null;
        } else {
            Calendar c = Calendar.getInstance();
            c.setTime(date);
            c.set(5, c.getActualMaximum(5));
            c.set(11, 23);
            c.set(12, 59);
            c.set(13, 59);
            c.set(14, 999);
            return c.getTime();
        }
    }

    public static Date getWeekBeginDay(Date date) {
        if (date == null) {
            return null;
        } else {
            Calendar c = Calendar.getInstance();
            c.setTime(date);
            c.setFirstDayOfWeek(2);
            c.set(7, 2);
            c.set(11, 0);
            c.set(12, 0);
            c.set(13, 0);
            c.set(12, 0);
            c.set(14, 0);
            return c.getTime();
        }
    }

    public static Date getWeekEndDay(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.setFirstDayOfWeek(2);
        c.set(7, 1);
        c.set(11, 23);
        c.set(12, 59);
        c.set(13, 59);
        c.set(14, 999);
        return c.getTime();
    }

    public static Date getDayBeginTime(Date date) {
        if (date == null) {
            return null;
        } else {
            Calendar c = Calendar.getInstance();
            c.setTime(date);
            c.set(11, 0);
            c.set(12, 0);
            c.set(13, 0);
            c.set(14, 0);
            return c.getTime();
        }
    }

    public static Date getDayEndTime(Date date) {
        if (date == null) {
            return null;
        } else {
            Calendar c = Calendar.getInstance();
            c.setTime(date);
            c.set(11, 23);
            c.set(12, 59);
            c.set(13, 59);
            c.set(14, 999);
            return c.getTime();
        }
    }

    public static String getDayBeginTime(String _date) {
        Date date = parse(_date, "yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(11, 0);
        c.set(12, 0);
        c.set(13, 0);
        c.set(14, 0);
        return format(c.getTime(), "yyyy-MM-dd HH:mm:ss.SSS");
    }

    public static String getDayEndTime(String _date) {
        Date date = parse(_date, "yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(11, 23);
        c.set(12, 59);
        c.set(13, 59);
        c.set(14, 999);
        return format(c.getTime(), "yyyy-MM-dd HH:mm:ss.SSS");
    }

    public static Date getHourBeginTime(Date date) {
        if (date == null) {
            return null;
        } else {
            Calendar c = Calendar.getInstance();
            c.setTime(date);
            c.set(12, 0);
            c.set(13, 0);
            c.set(14, 0);
            return c.getTime();
        }
    }

    public static Date getHourEndTime(Date date) {
        if (date == null) {
            return null;
        } else {
            Calendar c = Calendar.getInstance();
            c.setTime(date);
            c.set(12, 59);
            c.set(13, 59);
            c.set(14, 999);
            return c.getTime();
        }
    }

    public static String getDayName(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return DAY_NAMES[c.get(7) - 1];
    }

    public static String getWeekName(String type) {
        return (String)typeMap.get(type);
    }

    public static String getChineseWeekName(String type) {
        if (type.equals("0")) {
            type = "7";
        }

        return (String)typeMap.get(type);
    }

    public static String getDateString(long time) {
        StringBuffer timeContent = new StringBuffer();
        long t = time / 1000L;
        long tmpTime = t % 60L;
        if (tmpTime == 0L) {
            timeContent.append(String.format("%s'", t / 60L));
        } else {
            if (t / 60L > 0L) {
                timeContent.append(String.format("%s'", t / 60L));
            }

            timeContent.append(String.format("%s''", tmpTime));
        }

        return timeContent.toString();
    }

    public static String getDateString(Date startDate, Date endDate) {
        String sDate = format(startDate, "yyyyMMdd");
        String eDate = format(endDate, "yyyyMMdd");
        if (sDate.equals(eDate)) {
            return format(startDate, "MM月dd日");
        } else {
            String sBeginDay = CalendarUtil.getSeasonStartTime(startDate).replace("-", "");
            String sEndDay = CalendarUtil.getSeasonEndTime(startDate).replace("-", "");
            if (sBeginDay.equals(sDate) && sEndDay.equals(eDate)) {
                return CalendarUtil.getSeasonTitle(startDate);
            } else {
                String mBeginDay = format(getMonthBeginDay(startDate), "yyyyMMdd");
                String mEndDay = format(getMonthEndDay(endDate), "yyyyMMdd");
                return mBeginDay.equals(sDate) && mEndDay.equals(eDate) ? format(startDate, "yyyy年MM月") : format(startDate, "MM月dd日").concat("-").concat(format(endDate, "MM月dd日"));
            }
        }
    }

    public static Date getLastWeekMonday(Date date) {
        Date a = addDays(date);
        Calendar cal = Calendar.getInstance();
        cal.setTime(a);
        cal.add(3, -1);
        cal.set(7, 2);
        return cal.getTime();
    }

    public static Date getLastWeekSunday(Date date) {
        Date a = addDays(date);
        Calendar cal = Calendar.getInstance();
        cal.setTime(a);
        cal.set(7, 1);
        return cal.getTime();
    }

    public static Date addDays(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(7, -1);
        return cal.getTime();
    }

    public static Date getLastDay(Date date) {
        Date a = addDays(date);
        Calendar cal = Calendar.getInstance();
        cal.setTime(a);
        cal.add(5, 0);
        return cal.getTime();
    }

    public static int getCurrentDateDiffByDate(String date) {
        if (StringUtils.isBlank(date)) {
            return 0;
        } else {
            Date _date = parseDate(date);
            Calendar c1 = Calendar.getInstance();
            c1.setTime(new Date());
            Calendar c2 = Calendar.getInstance();
            c2.setTime(_date);
            return c1.get(1) - c2.get(1) < 0 ? 0 : c1.get(1) - c2.get(1);
        }
    }

    public static int getWeek(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int week = c.get(7);
        return week;
    }

    public static Date getLastMonthFirstDay(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(2, -1);
        c.set(5, 1);
        return c.getTime();
    }

    public static Date getLastMonthEndDay(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(2, -1);
        c.set(5, c.getActualMaximum(5));
        return c.getTime();
    }

    public static Date getLastMonth(Date date, int count) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(2, 0 - count);
        c.set(5, c.getActualMaximum(5));
        return c.getTime();
    }

    public static int daysOfTwo(Date fDate, Date oDate) {
        int days = (int)((oDate.getTime() - fDate.getTime()) / 86400000L);
        return days;
    }

    public static List<String> getDaysBetween(Date start, Date end, int workDays) {
        List<String> days = new ArrayList();
        SimpleDateFormat yearFormat = new SimpleDateFormat("yyyy");
        if (yearFormat.format(start).equals(yearFormat.format(end))) {
            days.addAll(getBetweenTwoDatesDays(start, end));
        } else {
            Date yearLast = getYearLast(start);
            days.addAll(getBetweenTwoDatesDays(start, yearLast));
            Date yearFirst = getYearFirst(end);
            days.addAll(getBetweenTwoDatesDays(yearFirst, end));
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        try {
            for(int r = days.size() - 1; r >= 0; --r) {
                int day = sdf.parse(days.get(r)).getDay();
                if (day == 0 || day > workDays) {
                    days.remove(r);
                }
            }
        } catch (ParseException var8) {
            log.error("", var8);
        }

        return days;
    }

    public static List<String> getBetweenTwoDatesDays(Date startDate, Date endDate) {
        int days = daysOfTwo(startDate, endDate) + 1;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        List<String> dates = new ArrayList();

        for(int i = 0; i < days; ++i) {
            dates.add(format(calendar.getTime(), "yyyy-MM-dd"));
            calendar.add(5, 1);
        }

        return dates;
    }

    public static List<String> getBetweenTwoDatesDays(Date startDate, Date endDate, String format) {
        int days = daysOfTwo(startDate, endDate) + 1;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        List<String> dates = new ArrayList();

        for(int i = 0; i < days; ++i) {
            dates.add(format(calendar.getTime(), format));
            calendar.add(5, 1);
        }

        return dates;
    }

    public static List<String> getBetweenTwoDatesDays(String startDay, String endDay) {
        return getBetweenTwoDatesDays(startDay, endDay, "yyyy-MM-dd");
    }

    public static List<String> getBetweenTwoDatesDays(String startDay, String endDay, String format) {
        List<String> list = new ArrayList();
        SimpleDateFormat sdf = new SimpleDateFormat(format);

        try {
            getBetweenTwoDatesDays(sdf.parse(startDay), sdf.parse(endDay));
        } catch (ParseException var6) {
            log.error(var6.getMessage(), var6);
        }

        return list;
    }

    public static Date getThisYearStartDate() {
        Date now = getNow();
        String year = format(now, "yyyy");
        Date date = parse(year + "-09-01", "yyyy-MM-dd");
        if (now.before(date)) {
            year = String.valueOf(Integer.parseInt(year) - 1);
        }

        return parse(year + "-09-01", "yyyy-MM-dd");
    }

    public static Date getThisYearEndDate() {
        Date now = getNow();
        String year = format(now, "yyyy");
        Date date = parse(year + "-08-31", "yyyy-MM-dd");
        if (now.after(date)) {
            year = String.valueOf(Integer.parseInt(year) + 1);
        }

        return parse(year + "-08-31", "yyyy-MM-dd");
    }

    public static String getYearName(Date date) {
        String year = format(date, "yyyy");
        Date d = parse(year + "-09-01", "yyyy-MM-dd");
        if (d.after(getYearFirst(date)) && d.before(parse(year + "-08-31", "yyyy-MM-dd"))) {
            year = String.valueOf(Integer.parseInt(year) - 1);
        }

        return year + "年度";
    }

    public static Date getCurrYearFirst() {
        return getYearFirst(getNow());
    }

    public static Date getCurrYearLast() {
        return getYearLast(getNow());
    }

    public static Date getYearFirst(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int year = calendar.get(1);
        calendar.clear();
        calendar.set(1, year);
        Date currYearFirst = calendar.getTime();
        return currYearFirst;
    }

    public static Date getYearLast(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int year = calendar.get(1);
        calendar.clear();
        calendar.set(1, year);
        calendar.roll(6, -1);
        Date currYearLast = calendar.getTime();
        return currYearLast;
    }

    public static boolean isYearFirstDay(Date now) {
        Calendar c = Calendar.getInstance();
        c.setTime(now);
        return 1 == c.get(5) && 0 == c.get(2);
    }

    public static boolean isYearLasttDay(Date now) {
        Calendar c = Calendar.getInstance();
        c.setTime(now);
        return 1 == c.get(5) && 0 == c.get(2);
    }

    public static boolean isMonthFirstDay(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return 1 == c.get(5);
    }

    public static boolean isMonthEndDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int specifyDayIndex = calendar.get(5);
        calendar.set(5, calendar.getActualMaximum(5));
        int endDayIndex = calendar.get(5);
        return specifyDayIndex == endDayIndex;
    }

    public static boolean isSameDay(Date day1, Date day2) {
        if (day1 != null && day2 != null) {
            Calendar c1 = Calendar.getInstance();
            c1.setTime(day1);
            c1.set(11, 0);
            c1.set(12, 0);
            c1.set(13, 0);
            c1.set(14, 0);
            Calendar c2 = Calendar.getInstance();
            c2.setTime(day2);
            c2.set(11, 0);
            c2.set(12, 0);
            c2.set(13, 0);
            c2.set(14, 0);
            return c1.getTime().getTime() == c2.getTime().getTime();
        } else {
            return false;
        }
    }

    public static boolean isSemesterFirstDay(Date now) {
        String date = format(now, "MM-dd");
        return date.equals("02-01") || date.equals("09-01");
    }

    public static boolean isSemesterEndDay(Date now) {
        String date = format(now, "MM-dd");
        return date.equals("08-31") || date.equals("01-31");
    }

    public static Date getSemesterBeginDay(Date date) {
        if (date == null) {
            return null;
        } else {
            Calendar c = Calendar.getInstance();
            c.setTime(date);
            int year = c.get(1);
            int month = c.get(2);
            if (month >= 1 && month <= 7) {
                c.set(year, 1, 1, 0, 0, 0);
            } else {
                c.set(year - 1, 8, 1, 0, 0, 0);
            }

            c.set(14, 0);
            return c.getTime();
        }
    }

    public static Date getSemesterEndDay(Date date) {
        if (date == null) {
            return null;
        } else {
            Calendar c = Calendar.getInstance();
            c.setTime(date);
            int year = c.get(1);
            int month = c.get(2);
            if (month >= 1 && month <= 7) {
                c.set(year, 7, 31, 0, 0, 0);
            } else {
                c.set(year, 0, 31, 0, 0, 0);
            }

            c.set(14, 0);
            return c.getTime();
        }
    }

    public static boolean isWeekFirstDay(Date now) {
        Calendar c = Calendar.getInstance();
        c.setTime(now);
        return c.get(7) == 2;
    }

    public static boolean isWeekLastDay(Date now) {
        Calendar c = Calendar.getInstance();
        c.setTime(now);
        return c.get(7) == 1;
    }

    public static boolean isMonthFirstWorkingDay(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(5, 1);
        int i = 1;

        while(cal.get(7) == 7 || cal.get(7) == 1) {
            cal.set(5, i++);
        }

        Date firWorkingDay = cal.getTime();
        return format(firWorkingDay, "yyyyMMdd").equals(format(date, "yyyyMMdd"));
    }

    public static Date getAfterMin(Date date, int min) {
        long time = date.getTime();
        long duration = (long)min * 1000L * 60L;
        return new Date(time + duration);
    }

    public static Date getAfterHour(Date date, int hour) {
        long time = date.getTime();
        long duration = (long)hour * 1000L * 60L * 60L;
        return new Date(time + duration);
    }

    public static Date getAfterYear(Date date, int size) {
        Calendar canlendar = Calendar.getInstance();
        canlendar.setTime(date);
        canlendar.add(1, size);
        return canlendar.getTime();
    }

    public static Date parseToDate(Long timestamp) {
        return timestamp <= 0L ? null : new Date(timestamp * 1000L);
    }

    public static List<String> getWeekDays(Date now, String pattern) {
        Date dBegin = getWeekBeginDay(now);
        Date dEnd = getWeekEndDay(now);
        List<String> lDate = new ArrayList();
        lDate.add(format(dBegin, pattern));
        dEnd = getDayBeginTime(dEnd);
        Calendar calBegin = Calendar.getInstance();
        calBegin.setTime(dBegin);

        while(dEnd.after(calBegin.getTime())) {
            calBegin.add(5, 1);
            lDate.add(format(calBegin.getTime(), pattern));
        }

        return lDate;
    }

    public static int computeWeek(Date startDate, Date endDate) {
        int weeks = 0;
        Calendar beginCalendar = Calendar.getInstance();
        beginCalendar.setTime(startDate);
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(endDate);

        while(beginCalendar.before(endCalendar) && (beginCalendar.get(1) != endCalendar.get(1) || beginCalendar.get(2) != endCalendar.get(2) || beginCalendar.get(8) != endCalendar.get(8))) {
            beginCalendar.add(6, 7);
            ++weeks;
        }

        return weeks;
    }

    public static long computeMinute(Date startDate, Date endDate) {
        if (startDate != null && endDate != null) {
            long diff = endDate.getTime() - startDate.getTime();
            long minute = diff / 60L / 1000L;
            return minute;
        } else {
            return 0L;
        }
    }

    public static List<String> listBetweenMonth(Date start, Date end) {
        List<String> result = new ArrayList();
        Calendar min = Calendar.getInstance();
        min.setTime(start);
        min.set(min.get(1), min.get(2), 1);
        Calendar max = Calendar.getInstance();
        max.setTime(end);
        max.set(max.get(1), max.get(2), 2);
        Calendar curr = min;

        while(curr.before(max)) {
            result.add(format(curr.getTime(), "yyyyMM"));
            curr.add(2, 1);
        }

        return result;
    }

    public static List<String> genrateWeekend(String beginDate, String endDate) {
        List<String> list = new ArrayList();
        Calendar c = Calendar.getInstance();
        c.setTime(parseDate(beginDate, "yyyyMMdd"));
        Calendar c2 = Calendar.getInstance();
        c2.setTime(parseDate(endDate, "yyyyMMdd"));

        for(; c.compareTo(c2) < 0; c.add(5, 1)) {
            if (c.get(7) == 7 || c.get(7) == 1) {
                list.add(format(c.getTime(), "yyyyMMdd"));
            }
        }

        return list;
    }

    public static Date initDateByDay(Date time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.set(11, 0);
        calendar.set(12, 0);
        calendar.set(13, 0);
        return calendar.getTime();
    }

    public static List<String> findDaysList(String begintTime, String endTime) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Date dBegin = null;
        Date dEnd = null;

        try {
            dBegin = sdf.parse(begintTime);
            dEnd = sdf.parse(endTime);
        } catch (ParseException var9) {
            var9.printStackTrace();
        }

        List<String> daysStrList = new ArrayList();
        daysStrList.add(sdf.format(dBegin));
        Calendar calBegin = Calendar.getInstance();
        calBegin.setTime(dBegin);
        Calendar calEnd = Calendar.getInstance();
        calEnd.setTime(dEnd);

        while(dEnd.after(calBegin.getTime())) {
            calBegin.add(5, 1);
            String dayStr = sdf.format(calBegin.getTime());
            daysStrList.add(dayStr);
        }

        return daysStrList;
    }

    public static String coverChineseDate(String format) {
        if (StringUtils.isBlank(format)) {
            return "";
        } else {
            String[] split = format.split("-");
            return split.length == 0 ? "" : split[0] + "月" + split[1] + "日";
        }
    }

    public static Date getNextDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(5, 1);
        date = calendar.getTime();
        return date;
    }

    public static Date addDay(Date date, int addDayNum) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(5, addDayNum);
        return calendar.getTime();
    }

    public static boolean isEffectiveTime(Date startTime, Date endTime, String format) {
        Date date = new Date();
        new SimpleDateFormat(format);
        date = parseDate(format(date, format), format);
        return isEffectiveTime(startTime, endTime, date);
    }

    public static boolean isEffectiveTime(Date startTime, Date endTime, Date date) {
        if (startTime != null && endTime != null && date != null) {
            long dateTime = date.getTime();
            if (startTime.getTime() != dateTime && endTime.getTime() != dateTime) {
                return date.after(startTime) && date.before(endTime);
            } else {
                return true;
            }
        } else {
            return false;
        }
    }

    public static Integer timeStr2Int(String time) {
        return Integer.parseInt(time.replace(":", ""));
    }

    public static String timeIntToStr(Integer time) {
        String s = String.valueOf(time);
        if (s.length() == 1) {
            s = "00:0" + s;
        } else if (s.length() == 2) {
            s = "00:" + s;
        } else if (s.length() == 3) {
            s = "0" + s.charAt(0) + ":" + s.substring(1, 3);
        } else if (s.length() == 4) {
            s = s.substring(0, 2) + ":" + s.substring(2, 4);
        }

        return s;
    }

    public static Date getCurrYearFirst(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(1, year);
        Date currYearFirst = calendar.getTime();
        return currYearFirst;
    }

    public static Date getCurrYearLast(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(1, year);
        calendar.roll(6, -1);
        Date currYearLast = calendar.getTime();
        return currYearLast;
    }

    public static int getAgeByBirth(Date birthday) {
        Calendar cal = Calendar.getInstance();
        Calendar bir = Calendar.getInstance();
        bir.setTime(birthday);
        if (cal.before(birthday)) {
            return 0;
        } else {
            int yearNow = cal.get(1);
            int monthNow = cal.get(2);
            int dayNow = cal.get(5);
            int yearBirth = bir.get(1);
            int monthBirth = bir.get(2);
            int dayBirth = bir.get(5);
            int age = yearNow - yearBirth;
            if (monthNow < monthBirth || monthNow == monthBirth && dayNow < dayBirth) {
                --age;
            }

            return age;
        }
    }

    public static Date getEndOfDay(Date date) {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());
        LocalDateTime endOfDay = localDateTime.with(LocalTime.MAX);
        return Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant());
    }

    public static Date getStartOfDay(Date date) {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());
        LocalDateTime startOfDay = localDateTime.with(LocalTime.MIN);
        return Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant());
    }

    public static Map<String, String> getWeekDate() {
        Map<String, String> map = new HashMap();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Calendar cal = Calendar.getInstance();
        cal.setFirstDayOfWeek(2);
        int dayWeek = cal.get(7);
        if (dayWeek == 1) {
            dayWeek = 8;
        }

        cal.add(5, cal.getFirstDayOfWeek() - dayWeek);
        cal.add(5, 7);
        Date mondayDate = cal.getTime();
        String weekBegin = sdf.format(mondayDate);
        cal.add(5, 4 + cal.getFirstDayOfWeek());
        Date sundayDate = cal.getTime();
        String weekEnd = sdf.format(sundayDate);
        map.put("mondayDate", weekBegin);
        map.put("sundayDate", weekEnd);
        return map;
    }

    public static long diffMinute(Date t1, Date t2) {
        if (t1 != null && t2 != null) {
            long l = t1.getTime() - t2.getTime();
            if (l > 0L) {
                long min = l / 60000L;
                return min;
            } else {
                return 0L;
            }
        } else {
            return 0L;
        }
    }

    public static Date addMin(Date date, int min) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(12, min);
        return cal.getTime();
    }

    public static Date Cal_Days(Date date, int days) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(5, calendar.get(5) + days);
        return calendar.getTime();
    }

    public static Boolean checkToday(Date date) {
        try {
            Date now = new Date();
            SimpleDateFormat sf = new SimpleDateFormat("yyyyMMdd");
            String nowDay = sf.format(now);
            String day = sf.format(date);
            return day.equals(nowDay);
        } catch (Exception var5) {
            log.error(var5.getMessage());
            return false;
        }
    }

    static {
        if (typeMap.size() == 0) {
            typeMap.put("1", "周一");
            typeMap.put("2", "周二");
            typeMap.put("3", "周三");
            typeMap.put("4", "周四");
            typeMap.put("5", "周五");
            typeMap.put("6", "周六");
            typeMap.put("7", "周日");
        }

    }
}

